home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / cmds / migcmd / RCS / migcmd.c,v < prev    next >
Encoding:
Text File  |  1990-09-24  |  24.3 KB  |  1,004 lines

  1. head     1.7;
  2. branch   ;
  3. access   ;
  4. symbols  ;
  5. locks    ; strict;
  6. comment  @ * @;
  7.  
  8.  
  9. 1.7
  10. date     90.09.24.14.39.06;  author douglis;  state Exp;
  11. branches ;
  12. next     1.6;
  13.  
  14. 1.6
  15. date     90.07.30.17.07.14;  author douglis;  state Exp;
  16. branches ;
  17. next     1.5;
  18.  
  19. 1.5
  20. date     90.02.06.16.41.19;  author douglis;  state Exp;
  21. branches ;
  22. next     1.4;
  23.  
  24. 1.4
  25. date     89.07.31.17.53.18;  author douglis;  state Exp;
  26. branches ;
  27. next     1.3;
  28.  
  29. 1.3
  30. date     89.04.29.14.35.12;  author douglis;  state Exp;
  31. branches ;
  32. next     1.2;
  33.  
  34. 1.2
  35. date     89.04.07.14.24.44;  author douglis;  state Exp;
  36. branches ;
  37. next     1.1;
  38.  
  39. 1.1
  40. date     88.12.06.13.49.14;  author douglis;  state Exp;
  41. branches ;
  42. next     ;
  43.  
  44.  
  45. desc
  46. @program to control process migration and interface to kernel debugging.
  47. @
  48.  
  49.  
  50. 1.7
  51. log
  52. @changes for statistics
  53. @
  54. text
  55. @/*
  56.  * migCmd.c --
  57.  *
  58.  *    Program to manipulate process migration characteristics and
  59.  *    perform other tasks related to migration.
  60.  *
  61.  * Copyright 1988, 1990 Regents of the University of California
  62.  * Permission to use, copy, modify, and distribute this
  63.  * software and its documentation for any purpose and without
  64.  * fee is hereby granted, provided that the above copyright
  65.  * notice appear in all copies.  The University of California
  66.  * makes no representations about the suitability of this
  67.  * software for any purpose.  It is provided "as is" without
  68.  * express or implied warranty.
  69.  */
  70.  
  71. #ifndef lint
  72. static char rcsid[] = "$Header: /sprite/src/cmds/migcmd/RCS/migcmd.c,v 1.6 90/07/30 17:07:14 douglis Exp Locker: douglis $ SPRITE (Berkeley)";
  73. #endif not lint
  74.  
  75. #include <sprite.h>
  76. #include <sysStats.h>
  77. #include <stdio.h>
  78. #include <stdlib.h>
  79. #include <option.h>
  80. #include <proc.h>
  81. #include <spriteTime.h>
  82. #include <kernel/sysSysCall.h>
  83. #include <kernel/trace.h>
  84. #include <kernel/procMigrate.h>
  85. #include <host.h>
  86.  
  87. #include "syscalls.h"
  88.  
  89. /*
  90.  * Variables for options.
  91.  */
  92.  
  93. int allowMigration = 0;
  94. int refuseMigration = 0;
  95. int getStatus = 0;
  96. int getMigStats = 0;
  97. int resetStats = 0;
  98. int input = -1;
  99. int load = -1;
  100. char *importStr = NULL;
  101. char *exportStr = NULL;
  102. int dumpTrace = 0;
  103. int startTrace = 0;
  104. int stopTrace = 0;
  105. int debugLevel = -1;
  106. int newVersion = -1;
  107. int numRecords = 200;
  108.  
  109. Option optionArray[] = {
  110.     {OPT_TRUE, "s", (Address)&getStatus,
  111.      "Print migration version, and conditions under which process migration is allowed."},
  112.     {OPT_TRUE, "S", (Address)&getMigStats,
  113.      "Print migration statistics."},
  114.     {OPT_TRUE, "Z", (Address)&resetStats,
  115.      "Reset migration statistics."},
  116.     {OPT_TRUE, "a", (Address)&allowMigration,
  117.      "Allow all future migrations to this machine (must be root)."},
  118.     {OPT_TRUE, "r", (Address)&refuseMigration,
  119.      "Disallow all future migrations to this machine (must be root)."},
  120.     {OPT_INT, "V", (Address)&newVersion,
  121.      "New migration version to set kernel version to."},
  122.     {OPT_INT, "i", (Address)&input,
  123.      "Whether to ignore idle time for allowing migrations to this machine."},
  124.     {OPT_INT, "l", (Address)&load,
  125.      "Whether to ignore load average for allowing migrations to this machine."},
  126.     {OPT_STRING, "I", (Address)&importStr,
  127.      "what users to allow to import (none, all, root)."},
  128.     {OPT_STRING, "E", (Address)&exportStr,
  129.      "what users to allow to export (none, all, root)."},
  130.     {OPT_TRUE, "p", (Address)&dumpTrace,
  131.      "Print process migration trace records."},
  132.     {OPT_INT, "P", (Address)&numRecords,
  133.      "Number of process migration records to print."},
  134.     {OPT_TRUE, "t", (Address)&startTrace,
  135.      "Enable tracing of process migration."},
  136.     {OPT_TRUE, "T", (Address)&stopTrace,
  137.      "Disable tracing of process migration."},
  138.     {OPT_INT, "d", (Address)&debugLevel,
  139.      "Level to set proc_MigDebugLevel."},
  140. };
  141. /*
  142.  * Constants used by tracing routines:
  143.  *     PROC_NUM_EVENTS - the number of valid trace events for proc.
  144.  */
  145.  
  146. #define PROC_NUM_EVENTS 5
  147.  
  148. /*
  149.  * For imports and exports, we either allow no one to migrate, just root,
  150.  * or everyone.
  151.  */
  152. #define ALLOW_NONE 0
  153. #define ALLOW_ROOT 1
  154. #define ALLOW_ALL 2
  155.  
  156. #define CheckBool(num) if((num) != 0 && (num) != 1) { \
  157.                     Opt_PrintUsage(argv[0], optionArray, \
  158.                            Opt_Number(optionArray)); \
  159.                    }
  160.  
  161. char *myName;
  162. void PrintState();
  163.  
  164. /*
  165.  *----------------------------------------------------------------------
  166.  *
  167.  * main --
  168.  *
  169.  *    Driver.
  170.  *
  171.  * Results:
  172.  *    None.
  173.  *
  174.  * Side effects:
  175.  *    Variable.
  176.  *
  177.  *----------------------------------------------------------------------
  178.  */
  179.  
  180.  
  181. main(argc, argv)
  182.     int argc;
  183.     char *argv[];
  184. {
  185.     ReturnStatus status = SUCCESS;
  186.     char          version[128];
  187.     int Status;
  188.     int changingState = 0;
  189.     int import = -1;
  190.     int export = -1;
  191.     int curVersion;
  192.  
  193.     (void) Opt_Parse(argc, argv, optionArray, Opt_Number(optionArray),
  194.              OPT_ALLOW_CLUSTERING);
  195.  
  196.     myName = argv[0];
  197.     
  198.     if (importStr != NULL) {
  199.     import = CheckString(importStr);
  200.     changingState = 1;
  201.     }
  202.     if (exportStr != NULL) {
  203.     export = CheckString(exportStr);
  204.     changingState = 1;
  205.     }
  206.     if (input != -1) {
  207.     CheckBool(input);
  208.     changingState = 1;
  209.     }
  210.     if (load != -1) {
  211.     CheckBool(load);
  212.     changingState = 1;
  213.     }
  214.              
  215.     if (allowMigration || refuseMigration) {
  216.     changingState = 1;
  217.     }
  218.     
  219.  
  220.     if (debugLevel != -1) {
  221.     status = Sys_Stats(SYS_PROC_MIGRATION, SYS_PROC_MIG_SET_DEBUG,
  222.                (Address) &debugLevel);
  223.     if (status != SUCCESS) {
  224.         Stat_PrintMsg(status, "Sys_Stats (set debug level)");
  225.         exit(status);
  226.     }
  227.     } 
  228.  
  229.     if (changingState || (newVersion != -1) || getStatus) {
  230.     status = Sys_Stats(SYS_PROC_MIGRATION, SYS_PROC_MIG_GET_STATE,
  231.                (Address) &Status);
  232.     if (status != SUCCESS) {
  233.         Stat_PrintMsg(status, "Sys_Stats (getting migration state)");
  234.         exit(status);
  235.     }
  236.     status = Sys_Stats(SYS_PROC_MIGRATION, SYS_PROC_MIG_GET_VERSION,
  237.                (Address) &curVersion);
  238.     if (status != SUCCESS) {
  239.         Stat_PrintMsg(status, "Sys_Stats (getting migration version)");
  240.         exit(status);
  241.     }
  242.     printf("\t\tImport\tExport\tVersion\tIgnore\n");
  243.     PrintState(Status, curVersion, "Current:");
  244.  
  245.     if (changingState) {
  246.         if (allowMigration) {
  247.         Status |= PROC_MIG_IMPORT_ALL;
  248.         } else if (refuseMigration) {
  249.         Status &= ~PROC_MIG_IMPORT_ALL;
  250.         } else if (import != -1) {
  251.         if (import == ALLOW_ALL) {
  252.             Status |= PROC_MIG_IMPORT_ALL;
  253.         } else if (import == ALLOW_NONE) {
  254.             Status &= ~PROC_MIG_IMPORT_ALL;
  255.         } else if (import == ALLOW_ROOT) {
  256.             Status &= ~PROC_MIG_IMPORT_ALL;
  257.             Status |= PROC_MIG_IMPORT_ROOT;
  258.         }
  259.         }
  260.         if (export != -1) {
  261.         if (export == ALLOW_ALL) {
  262.             Status |= PROC_MIG_EXPORT_ALL;
  263.         } else if (export == ALLOW_NONE) {
  264.             Status &= ~PROC_MIG_EXPORT_ALL;
  265.         } else if (export == ALLOW_ROOT) {
  266.             Status &= ~PROC_MIG_EXPORT_ALL;
  267.             Status |= PROC_MIG_EXPORT_ROOT;
  268.         }
  269.         }
  270.         if (input == 0) {
  271.         Status &= ~PROC_MIG_IMPORT_ANYINPUT;
  272.         } else if (input == 1) {
  273.         Status |= PROC_MIG_IMPORT_ANYINPUT;
  274.         }
  275.         if (load == 0) {
  276.         Status &= ~PROC_MIG_IMPORT_ANYLOAD;
  277.         } else if (load == 1) {
  278.         Status |= PROC_MIG_IMPORT_ANYLOAD;
  279.         }
  280.         
  281.         status = Sys_Stats(SYS_PROC_MIGRATION, SYS_PROC_MIG_SET_STATE,
  282.                    (Address) &Status);
  283.         if (status != SUCCESS) {
  284.         Stat_PrintMsg(status, "Sys_Stats (setting migration state)");
  285.         exit(status);
  286.         }
  287.     }
  288.     if (newVersion != -1) {
  289.         status = Sys_Stats(SYS_PROC_MIGRATION, SYS_PROC_MIG_SET_VERSION,
  290.                    (Address) &newVersion);
  291.         if (status != SUCCESS) {
  292.         Stat_PrintMsg(status, "Sys_Stats (setting migration version)");
  293.         exit(status);
  294.         }
  295.     }
  296.     if (changingState || (newVersion != -1)) {
  297.         PrintState(Status, (newVersion != -1) ? newVersion : curVersion,
  298.                "New:\t");
  299.     }
  300.     }
  301.     if (startTrace) {
  302.     status = Sys_Stats(SYS_PROC_TRACE_STATS, SYS_PROC_TRACING_ON,
  303.             (Address) NULL);
  304.     if (status != SUCCESS) {
  305.         (void) fprintf(stderr, "Error %x returned from Test_Stats.\n",
  306.                status);
  307.         Stat_PrintMsg(status, "");
  308.         exit(status);
  309.     }
  310.     }
  311.  
  312.     if (stopTrace) {
  313.     status = Sys_Stats(SYS_PROC_TRACE_STATS, SYS_PROC_TRACING_OFF,
  314.             (Address) NULL);
  315.     if (status != SUCCESS) {
  316.         (void) fprintf(stderr, "Error %x returned from Test_Stats.\n",
  317.                status);
  318.         Stat_PrintMsg(status, "");
  319.         exit(status);
  320.     }
  321.     }
  322.  
  323.     if (dumpTrace) {
  324.     status = PrintMigration();
  325.     }
  326.  
  327.     if (resetStats) {
  328.     status = Sys_Stats(SYS_PROC_MIGRATION, SYS_PROC_MIG_RESET_STATS,
  329.             (Address) NULL);
  330.     if (status != SUCCESS) {
  331.         (void) fprintf(stderr,
  332.                "Error %x returned from Sys_Stats resetting statistics.\n",
  333.                status);
  334.         Stat_PrintMsg(status, "");
  335.         exit(status);
  336.     }
  337.     }
  338.  
  339.     if (getMigStats) {
  340.     status = PrintStats();
  341.     }
  342.  
  343.  
  344.     exit(status);
  345. }
  346.  
  347.  
  348. /*
  349.  *----------------------------------------------------------------------
  350.  *
  351.  * PrintMigration --
  352.  *
  353.  *    Print the most recent process migration trace records.
  354.  *
  355.  * Results:
  356.  *    The return status from Sys_Stats is returned.
  357.  *
  358.  * Side effects:
  359.  *    Trace records are written to stdout.
  360.  *
  361.  *----------------------------------------------------------------------
  362.  */
  363.  
  364.  
  365. int
  366. PrintMigration()
  367. {
  368.     int index;        /* index of current table entry */
  369.     Time baseTime, deltaTime, startTime;    /* Times for print out */
  370.     Address buffer;    /* Buffer for trace records */
  371.     int numRecs;        /* number of records actually copied */
  372.     Trace_Record *traceArray;
  373.     Proc_TraceRecord *procTraceArray;
  374.     register Trace_Record *tracePtr;
  375.     register Proc_TraceRecord *procTracePtr;
  376.     int status;
  377.     static char *flagsArray[] = {"RE", "RS", "HE", "HS", "  "};
  378.     static char *eventArray[] = {"start", "end", "xfer", "call", "migtrap"};
  379.     static char *commandArray[] = {"proc", "vm", "files", "stream", "user",
  380.                  "resume"};
  381.     /*
  382.      * Get a copy of the trace table.
  383.      */
  384.  
  385.     buffer = malloc((unsigned) (sizeof(int) + numRecords *
  386.                 (sizeof(Trace_Record) +
  387.                  sizeof(Proc_TraceRecord))));
  388.     status = Sys_Stats(SYS_PROC_TRACE_STATS, numRecords, buffer);
  389.     if (status != SUCCESS) {
  390.     (void) fprintf(stderr, "Error from Sys_Stats.\n");
  391.     Stat_PrintMsg(status, "");
  392.     return(status);
  393.     }
  394.  
  395.     numRecs = * ((int *) buffer);
  396.     buffer += sizeof(int);
  397.     (void) fprintf(stderr, "Number of records is %d.\n", numRecs);
  398.     (void) fflush(stderr);
  399.     if (numRecs == 0) {
  400.     return(0);
  401.     }
  402.  
  403.     traceArray = (Trace_Record *) buffer;
  404.     procTraceArray = (Proc_TraceRecord *) (buffer + numRecs *
  405.                      sizeof(Trace_Record));
  406.  
  407.  
  408.     (void) printf("\n");
  409. #define PRINT_MIGHEADER() \
  410.     (void) printf("%10s %10s %10s %2s %10s %24s %7s\n", \
  411.     "Time", "Delta", "ProcessID", "HR", "Event", "Call", "Sta")
  412.     PRINT_MIGHEADER();
  413.  
  414.     baseTime = traceArray[0].time;
  415.     startTime = traceArray[0].time;
  416.  
  417.     for (index = 0; index < numRecs; index++) {
  418.     tracePtr = &traceArray[index];
  419.     procTracePtr = &procTraceArray[index];
  420.  
  421.     Time_Subtract(tracePtr->time, startTime, &deltaTime);
  422.     (void) printf(" %3d.%06d",
  423.                deltaTime.seconds,
  424.                deltaTime.microseconds);
  425.     Time_Subtract(tracePtr->time, baseTime, &deltaTime);
  426.     (void) printf(" %3d.%06d",
  427.                deltaTime.seconds,
  428.                deltaTime.microseconds);
  429.     baseTime = tracePtr->time;
  430.  
  431.     if (tracePtr->flags & TRACE_DATA_INVALID) {
  432.         procTracePtr->flags = 4;
  433.         procTracePtr->processID = (Proc_PID) NULL;
  434.     }
  435.     if (((unsigned) procTracePtr->flags) > 3 ||
  436.         ((unsigned) tracePtr->event)  >= PROC_NUM_EVENTS) {
  437.         (void) fprintf(stderr,
  438.                    "Entry %d: invalid flags (%d) or event (%d).\n",
  439.                    index, procTracePtr->flags, tracePtr->event);
  440.         return(-1);
  441.         }
  442.  
  443.     (void) printf("%10x %3s %10s", procTracePtr->processID,
  444.               flagsArray[procTracePtr->flags],
  445.               eventArray[tracePtr->event]);
  446.  
  447.     if (tracePtr->event == PROC_MIGTRACE_COMMAND) {
  448.         (void) printf(" %-10s",
  449.              commandArray[(int) procTracePtr->info.command.type]);
  450.         if (procTracePtr->info.command.data != (ClientData) NIL) {
  451.         (void) printf(" %20d",
  452.                    procTracePtr->info.command.data);
  453.         }
  454.     } else if (tracePtr->event == PROC_MIGTRACE_CALL) {
  455.         (void) printf(" %24s",
  456.              sysCallArray[(int) procTracePtr->info.call.callNumber].name);
  457.         if (!(procTracePtr->flags & PROC_MIGTRACE_START)) {
  458.         (void) printf(" %10x",
  459.                    procTracePtr->info.call.status);
  460.         }
  461.     }
  462.  
  463.     (void) printf("\n");
  464.     }
  465.     PRINT_MIGHEADER();
  466.     return(0);
  467. }
  468.  
  469.  
  470. /*
  471.  *----------------------------------------------------------------------
  472.  *
  473.  * PrintState --
  474.  *
  475.  *    Print the process migration state defined by the status word in
  476.  *    the kernel.
  477.  *
  478.  * Results:
  479.  *    None.
  480.  *
  481.  * Side effects:
  482.  *    Prints to stdout.
  483.  *
  484.  *----------------------------------------------------------------------
  485.  */
  486.  
  487. void
  488. PrintState(state, version, prelude)
  489.     int state;
  490.     int version;
  491.     char *prelude;
  492. {
  493.     int tmp;
  494.     char *import;
  495.     char *export;
  496.     int extra = 0;
  497.  
  498.     tmp = state & PROC_MIG_IMPORT_ALL;
  499.     if (tmp == 0) {
  500.     import = "none";
  501.     } else if (tmp == PROC_MIG_IMPORT_ROOT) {
  502.     import = "root";
  503.     } else{
  504.     import = "all";
  505.     }
  506.     tmp = state & PROC_MIG_EXPORT_ALL;
  507.     if (tmp == 0) {
  508.     export = "none";
  509.     } else if (tmp == PROC_MIG_EXPORT_ROOT) {
  510.     export = "root";
  511.     } else{
  512.     export = "all";
  513.     }
  514.     
  515.     printf("%s\t%4s\t%4s\t%4d\t", prelude, import, export, version);
  516.     if (state & PROC_MIG_IMPORT_ANYLOAD) {
  517.     printf("load");
  518.     extra = 1;
  519.     }
  520.     if (state & PROC_MIG_IMPORT_ANYINPUT) {
  521.     if (extra) {
  522.         printf(", ");
  523.     }
  524.     printf("input");
  525.     }
  526.     printf("\n");
  527. }
  528.  
  529.  
  530.  
  531.  
  532. /*
  533.  *----------------------------------------------------------------------
  534.  *
  535.  * CheckString --
  536.  *
  537.  *    Verify that a string conforms to one of the allowable options
  538.  *    and return that option.
  539.  *
  540.  * Results:
  541.  *    The constant corresponding to the string is returned.
  542.  *
  543.  * Side effects:
  544.  *    If the string is not allowable, an error message is printed and
  545.  *    the process exits.
  546.  *
  547.  *----------------------------------------------------------------------
  548.  */
  549.  
  550. int
  551. CheckString(string)
  552.     char *string;
  553. {
  554.     if(!strcmp(string, "all")) {
  555.     return(ALLOW_ALL);
  556.     }
  557.     if(!strcmp(string, "root")) {
  558.     return(ALLOW_ROOT);
  559.     }
  560.     if(!strcmp(string, "none")) {
  561.     return(ALLOW_NONE);
  562.     }
  563.     Opt_PrintUsage(myName, optionArray, Opt_Number(optionArray));
  564.     exit(1);
  565. }
  566.  
  567.  
  568. /*
  569.  *----------------------------------------------------------------------
  570.  *
  571.  * PrintStats --
  572.  *
  573.  *    Print migration statistics.
  574.  *
  575.  * Results:
  576.  *    The return status from Sys_Stats is returned.
  577.  *
  578.  * Side effects:
  579.  *    Statistics are written to stdout.
  580.  *
  581.  *----------------------------------------------------------------------
  582.  */
  583.  
  584.  
  585. int
  586. PrintStats()
  587. {
  588.     Proc_MigStats stats;        /* statistics */
  589.     int status;
  590.     Time avgTime;
  591.     double time;
  592.     double time2;
  593.     int i;
  594.     Host_Entry *hostPtr;
  595.  
  596.     /*
  597.      * Get a copy of the statistics record.  Make sure it's zeroed in case the
  598.      * kernel provides us with a shorter (older) structure.
  599.      */
  600.  
  601.     bzero((Address) &stats, sizeof(stats));
  602.     status = Sys_Stats(SYS_PROC_MIGRATION, SYS_PROC_MIG_GET_STATS,
  603.                (Address) &stats);
  604.     if (status != SUCCESS) {
  605.     (void) fprintf(stderr, "Error from Sys_Stats.\n");
  606.     Stat_PrintMsg(status, "");
  607.     return(status);
  608.     }
  609.  
  610.     if (stats.statsVersion != PROC_MIG_STATS_VERSION) {
  611.     (void) fprintf(stderr, "Different versions of statistics buffer.\n");
  612.     return(FAILURE);
  613.     }
  614.  
  615. #define PRINT(string, val) printf("%40s\t%d\n", string, stats.val)
  616.  
  617.     PRINT("Number of foreign processes", foreign);
  618.     PRINT("Number of remote processes", remote);
  619.     PRINT("Number of exports", exports);
  620.     PRINT("Number of execs", execs);
  621.     PRINT("Number of imports", imports);
  622.     PRINT("Number of errors", errors);
  623.     PRINT("Number of eviction requests", evictCalls);
  624.     PRINT("Number resulting in evictions", evictsNeeded);
  625.     PRINT("Number of evicted processes", varStats.evictions);
  626.     PRINT("Number voluntary migrations home", migrationsHome);
  627.     PRINT("Number of returns to us", returns);
  628.     PRINT("Number of evictions back to us", evictionsToUs);
  629.     if (stats.evictionsToUs > 0) {
  630.     time = stats.varStats.evictionCPUTime / stats.evictionsToUs;
  631.     } else {
  632.     time = 0;
  633.     }
  634.     printf("%40s\t%7.3f\n", "Average time used after eviction", time);
  635.  
  636.     PRINT("Number of pages written", varStats.pagesWritten);
  637.     if (stats.exports - stats.execs > 0) {
  638.     time = stats.varStats.timeToMigrate /
  639.         (stats.exports + stats.varStats.evictions - stats.execs);
  640.     } else {
  641.     time = 0;
  642.     }
  643.     printf("%40s\t%7.3f\n", "Average time to export", time);
  644.     if (stats.execs > 0) {
  645.     time = stats.varStats.timeToExec / stats.execs;
  646.     } else {
  647.     time = 0;
  648.     }
  649.     printf("%40s\t%7.3f\n", "Average time to exec", time);
  650.  
  651.     if (stats.varStats.evictions > 0) {
  652.     time = stats.varStats.timeToEvict / stats.varStats.evictions;
  653.     } else {
  654.     time = 0;
  655.     }
  656.     printf("%40s\t%7.3f\n", "Average time to evict 1 process", time);
  657.  
  658.     if (stats.evictsNeeded > 0) {
  659.     time = stats.varStats.totalEvictTime / stats.evictsNeeded;
  660.     } else {
  661.     time = 0;
  662.     }
  663.     printf("%40s\t%7.3f\n", "Average time to complete eviction", time);
  664.  
  665.  
  666.     printf("%40s\t%d\n", "Average Kbytes/migration",
  667.        ((stats.exports + stats.varStats.evictions) > 0) ? 
  668.        stats.varStats.rpcKbytes / (stats.exports + stats.varStats.evictions) :
  669.        0);
  670.     printf("%40s\t%d\n", "Average Kbytes/migration",
  671.        ((stats.exports + stats.varStats.evictions) > 0) ? 
  672.        stats.varStats.rpcKbytes / (stats.exports + stats.varStats.evictions) :
  673.        0);
  674.     printf("%40s\t%d/%d (%5.2f%%)\n", "Remote/Total CPU seconds",
  675.        stats.varStats.remoteCPUTime / 10, stats.varStats.totalCPUTime / 10,
  676.        ((double) stats.varStats.remoteCPUTime)/
  677.        stats.varStats.totalCPUTime * 100.0);
  678.     printf("\n%40s\t%s\n", "Host", "count");
  679.     Host_Start();
  680.     while (1) {
  681.     hostPtr = Host_Next();
  682.     if (hostPtr == (Host_Entry *) NULL) {
  683.         break;
  684.     }
  685.     if (stats.hostCounts[hostPtr->id]) {
  686.         printf("%40s\t%d\n", hostPtr->name, stats.hostCounts[hostPtr->id]);
  687.     }
  688.     }
  689.     Host_End();
  690.     return(SUCCESS);
  691. }
  692. @
  693.  
  694.  
  695. 1.6
  696. log
  697. @changes for statistics
  698. @
  699. text
  700. @d7 1
  701. a7 1
  702.  * Copyright 1988 Regents of the University of California
  703. d18 1
  704. a18 1
  705. static char rcsid[] = "$Header: /sprite/src/cmds/migcmd/RCS/migcmd.c,v 1.5 90/02/06 16:41:19 douglis Exp Locker: douglis $ SPRITE (Berkeley)";
  706. d556 1
  707. a556 6
  708.     /*
  709.      * This really should be defined in procMigrate.h....
  710.      */
  711. #define WANT_VERSION 1001
  712. #ifdef WANT_VERSION
  713.     if (stats.statsVersion != WANT_VERSION) {
  714. a559 1
  715. #endif
  716. d574 8
  717. d596 8
  718. d605 1
  719. a605 1
  720.     time = stats.varStats.timeToEvict / stats.evictsNeeded;
  721. d609 7
  722. a615 1
  723.     printf("%40s\t%7.3f\n", "Average time to evict", time);
  724. d620 4
  725. a623 6
  726.     if (stats.statsVersion > 0) {
  727.     printf("%40s\t%d/%d (%5.2f%%)\n", "Remote/Total CPU seconds",
  728.            stats.varStats.remoteCPUTime / 1000, stats.varStats.totalCPUTime / 1000,
  729.            ((double) stats.varStats.remoteCPUTime)/
  730.            stats.varStats.totalCPUTime * 100.0);
  731.     }
  732. @
  733.  
  734.  
  735. 1.5
  736. log
  737. @some changes for statistics, and zeroing them (wrong arg originally)
  738. @
  739. text
  740. @d18 1
  741. a18 1
  742. static char rcsid[] = "$Header: /a/newcmds/migcmd/RCS/migcmd.c,v 1.4 89/07/31 17:53:18 douglis Exp Locker: douglis $ SPRITE (Berkeley)";
  743. d556 10
  744. d577 1
  745. a577 1
  746.     PRINT("Number of evicted processes", evictions);
  747. d580 1
  748. a580 1
  749.     PRINT("Number of pages written", pagesWritten);
  750. d582 2
  751. a583 2
  752.     Time_Divide(stats.timeToMigrate, stats.exports + stats.evictions - stats.execs, &avgTime);
  753.     time = avgTime.seconds + ((double) avgTime.microseconds) / 1000000;
  754. d589 1
  755. a589 2
  756.     Time_Divide(stats.timeToExec, stats.execs, &avgTime);
  757.     time = avgTime.seconds + ((double) avgTime.microseconds) / 1000000;
  758. d595 1
  759. a595 2
  760.     Time_Divide(stats.timeToEvict, stats.evictsNeeded, &avgTime);
  761.     time = avgTime.seconds + ((double) avgTime.microseconds) / 1000000;
  762. d601 2
  763. a602 2
  764.        ((stats.exports + stats.evictions) > 0) ? 
  765.        stats.rpcKbytes / (stats.exports + stats.evictions) :
  766. d606 3
  767. a608 3
  768.            stats.remoteCPUTime.time.seconds, stats.totalCPUTime.time.seconds,
  769.            ((double) stats.remoteCPUTime.time.seconds)/
  770.            stats.totalCPUTime.time.seconds * 100.0);
  771. @
  772.  
  773.  
  774. 1.4
  775. log
  776. @print kernel statistics
  777. @
  778. text
  779. @d18 1
  780. a18 1
  781. static char rcsid[] = "$Header: /a/newcmds/migcmd/RCS/migcmd.c,v 1.3 89/04/29 14:35:12 douglis Exp Locker: douglis $ SPRITE (Berkeley)";
  782. d243 2
  783. a244 1
  784.         PrintState(Status, newVersion, "New:\t");
  785. d274 1
  786. a274 1
  787.     status = Sys_Stats(SYS_PROC_TRACE_STATS, SYS_PROC_MIG_RESET_STATS,
  788. d538 1
  789. d543 2
  790. a544 1
  791.      * Get a copy of the trace table.
  792. d547 1
  793. d557 1
  794. a557 1
  795. #define PRINT(string, val) printf("%30s\t%d\n", string, stats.val)
  796. d565 4
  797. a568 1
  798.     PRINT("Number of evictions from us", evictions);
  799. d572 1
  800. a572 1
  801.     Time_Divide(stats.timeToExport, stats.exports - stats.execs, &avgTime);
  802. d577 1
  803. a577 1
  804.     printf("%30s\t%7.3f\n", "Average time to export", time);
  805. d584 3
  806. a586 3
  807.     printf("%30s\t%7.3f\n", "Average time to exec", time);
  808.     if (stats.evictions > 0) {
  809.     Time_Divide(stats.timeToEvict, stats.evictions, &avgTime);
  810. d591 2
  811. a592 2
  812.     printf("%30s\t%7.3f\n", "Average time to evict", time);
  813.     printf("%30s\t%d\n", "Average Kbytes/migration",
  814. d596 7
  815. a602 2
  816.  
  817.     printf("\n%30s\t%s\n", "Host", "count");
  818. d610 1
  819. a610 1
  820.         printf("%30s\t%d\n", hostPtr->name, stats.hostCounts[hostPtr->id]);
  821. @
  822.  
  823.  
  824. 1.3
  825. log
  826. @removed duplicate option lines.
  827. @
  828. text
  829. @d18 1
  830. a18 1
  831. static char rcsid[] = "$Header: /a/newcmds/migcmd/RCS/migcmd.c,v 1.2 89/04/07 14:24:44 douglis Exp Locker: douglis $ SPRITE (Berkeley)";
  832. d27 1
  833. d31 1
  834. d41 3
  835. a43 1
  836. int getMigStatus = 0;
  837. d52 1
  838. d56 6
  839. a61 2
  840.     {OPT_TRUE, "m", (Address)&getMigStatus,
  841.      "Print conditions under which process migration is allowed (DEFAULT)."},
  842. d66 2
  843. d133 1
  844. a133 1
  845.     int migStatus;
  846. d137 1
  847. a163 7
  848.     /*
  849.      * Default operation is to get the migration status.
  850.      */
  851.     if (! (changingState || (debugLevel != -1) || dumpTrace ||
  852.        startTrace || stopTrace)) {
  853.     getMigStatus = 1;
  854.     }
  855. d175 1
  856. a175 1
  857.     if (changingState || getMigStatus) {
  858. d177 1
  859. a177 1
  860.                (Address) &migStatus);
  861. d182 8
  862. a189 2
  863.     printf("\t\tImport\tExport\tIgnore\n");
  864.     PrintState(migStatus, "Current:");
  865. d193 1
  866. a193 1
  867.         migStatus |= PROC_MIG_IMPORT_ALL;
  868. d195 1
  869. a195 1
  870.         migStatus &= ~PROC_MIG_IMPORT_ALL;
  871. d198 1
  872. a198 1
  873.             migStatus |= PROC_MIG_IMPORT_ALL;
  874. d200 1
  875. a200 1
  876.             migStatus &= ~PROC_MIG_IMPORT_ALL;
  877. d202 2
  878. a203 2
  879.             migStatus &= ~PROC_MIG_IMPORT_ALL;
  880.             migStatus |= PROC_MIG_IMPORT_ROOT;
  881. d208 1
  882. a208 1
  883.             migStatus |= PROC_MIG_EXPORT_ALL;
  884. d210 1
  885. a210 1
  886.             migStatus &= ~PROC_MIG_EXPORT_ALL;
  887. d212 2
  888. a213 2
  889.             migStatus &= ~PROC_MIG_EXPORT_ALL;
  890.             migStatus |= PROC_MIG_EXPORT_ROOT;
  891. d217 1
  892. a217 1
  893.         migStatus &= ~PROC_MIG_IMPORT_ANYINPUT;
  894. d219 1
  895. a219 1
  896.         migStatus |= PROC_MIG_IMPORT_ANYINPUT;
  897. d222 1
  898. a222 1
  899.         migStatus &= ~PROC_MIG_IMPORT_ANYLOAD;
  900. d224 1
  901. a224 1
  902.         migStatus |= PROC_MIG_IMPORT_ANYLOAD;
  903. d228 1
  904. a228 1
  905.                    (Address) &migStatus);
  906. d233 8
  907. a240 1
  908.         PrintState(migStatus, "New:\t");
  909. d242 3
  910. d272 17
  911. d433 1
  912. a433 1
  913. PrintState(state, prelude)
  914. d435 1
  915. d460 1
  916. a460 1
  917.     printf("%s\t%4s\t%4s\t", prelude, import, export);
  918. d510 93
  919. @
  920.  
  921.  
  922. 1.2
  923. log
  924. @changed to handle new kernel state variable.
  925. @
  926. text
  927. @d18 1
  928. a18 1
  929. static char rcsid[] = "$Header: /a/newcmds/migcmd/RCS/migcmd.c,v 1.1 88/12/06 13:49:14 douglis Exp Locker: douglis $ SPRITE (Berkeley)";
  930. a64 4
  931.     {OPT_TRUE, "p", (Address)&dumpTrace,
  932.      "Print process migration trace records."},
  933.     {OPT_TRUE, "p", (Address)&dumpTrace,
  934.      "Print process migration trace records."},
  935. @
  936.  
  937.  
  938. 1.1
  939. log
  940. @Initial revision
  941. @
  942. text
  943. @d18 1
  944. a18 1
  945. static char rcsid[] = "$Header: /a/newcmds/sysstat/RCS/sysstat.c,v 1.1 88/10/31 13:57:46 douglis Exp Locker: douglis $ SPRITE (Berkeley)";
  946. d26 1
  947. d40 4
  948. d52 1
  949. a52 1
  950.      "Print whether process migration is allowed (DEFAULT)."},
  951. d54 1
  952. a54 1
  953.      "Allow future migrations to this machine (must be root)."},
  954. d56 9
  955. a64 1
  956.      "Disallow future migrations to this machine (must be root)."},
  957. d67 4
  958. d87 15
  959. d127 3
  960. d134 22
  961. d159 2
  962. a160 2
  963.     if (! (allowMigration || refuseMigration || getMigStatus ||
  964.        (debugLevel != -1) || dumpTrace || startTrace || stopTrace)) {
  965. d164 1
  966. d174 2
  967. a175 2
  968.     if (allowMigration || refuseMigration || getMigStatus) {
  969.     status = Sys_Stats(SYS_PROC_MIGRATION, SYS_PROC_MIG_GET_STATUS,
  970. d178 1
  971. a178 1
  972.         Stat_PrintMsg(status, "Sys_Stats (getting migration status)");
  973. d181 2
  974. d184 34
  975. a217 6
  976.     if (allowMigration) {
  977.         status = Sys_Stats(SYS_PROC_MIGRATION, SYS_PROC_MIG_ALLOW,
  978.                    (Address) NULL);
  979.         if (status != SUCCESS) {
  980.         Stat_PrintMsg(status, "Sys_Stats (allow migration)");
  981.         exit(status);
  982. d219 3
  983. a221 5
  984.         (void) printf("Migration is currently allowed, previously %s.\n",
  985.              migStatus ? "refused" : "allowed");
  986.     } else if (refuseMigration) {
  987.         status = Sys_Stats(SYS_PROC_MIGRATION, SYS_PROC_MIG_REFUSE,
  988.                    (Address) NULL);
  989. d223 1
  990. a223 1
  991.         Stat_PrintMsg(status, "Sys_Stats (refuse migration)");
  992. d226 1
  993. a226 5
  994.         (void) printf("Migration is currently refused, previously %s.\n",
  995.              migStatus ? "refused" : "allowed");
  996.     } else {
  997.         (void) printf("Migration is currently %s.\n",
  998.              migStatus ? "refused" : "allowed");
  999. d358 1
  1000. a358 1
  1001.     if (tracePtr->event == PROC_MIGTRACE_TRANSFER) {
  1002. d379 97
  1003. @
  1004.